package org.zfes.snowier.zbss.xzy.store.queue;

import java.util.Collection;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.StampedLock;

import com.google.common.collect.Lists;

public class PersisitQueue extends ConcurrentLinkedQueue{
	
	
	private volatile AtomicInteger size = new AtomicInteger(0);
	

	 private final ReadWriteLock lock = new ReentrantReadWriteLock();
	 private final Lock readLock = lock.readLock();
	 private final Lock writeLock = lock.writeLock();
	 private final StampedLock sl = new StampedLock();
	@Override
	public boolean add(Object e) {
		//long stamp =this.sl.writeLock();
		try {
//			this.writeLock.lock();
		
			 boolean isOk=super.add(e);
				if(isOk) {
					size.incrementAndGet();
				}
				return isOk;
				
		}finally {
			//this.writeLock.unlock();
			// sl.unlockWrite(stamp);//释放写锁
		}
		
	}
	
	@Override
	public boolean addAll(Collection c) {
		//long stamp =this.sl.writeLock();
		try {
			//this.writeLock.lock();
		
			boolean isOk=super.addAll( c);
			if(isOk) {
				//size.incrementAndGet();
				size.getAndAdd(c.size());
			}
			return isOk;
		}finally {
//			this.writeLock.unlock();
		//	sl.unlockWrite(stamp);//释放写锁
		}
	}
	
	@Override
	public boolean offer(Object e) {
		//long stamp =this.sl.writeLock();
		try {
			//this.writeLock.lock();
			boolean isOk=super.offer(e);
			if(isOk) {
				size.incrementAndGet();
			}
			return isOk;
		}finally {
//			this.writeLock.unlock();
		//	sl.unlockWrite(stamp);//释放写锁
		}
	}

	@Override
	public Object poll() {
		//long stamp = sl.readLock();
		try {
//			this.readLock.lock();
			Object obj= super.poll();
			if(obj!=null) {
				size.decrementAndGet();
			}
			return obj;
		}finally {
//			this.readLock.unlock();
		//	 sl.unlockRead(stamp);
		}
	}
	
	public List<Object> poll(int count) {
		//long stamp = sl.readLock();
		
		try {
//			this.readLock.lock();
			int i=0;
			List<Object> dataList=Lists.newArrayList();
			Object data = super.poll();
			if(data==null) {
				return dataList;
			}
			dataList.add(data);
			
			size.decrementAndGet();
			
			int coun=count-1;
			while(i < coun && data!=null) {
				data = super.poll();
				if(data!=null) {
					dataList.add(data);
					size.decrementAndGet();
				}
				i++;
			}
			return dataList;
		}finally {
//			this.readLock.unlock();
		//	 sl.unlockRead(stamp);
		}
	}
	

	@Override
	public int size() {
		return size.intValue();
	}

	@Override
	public boolean remove(Object o) {
		try {this.writeLock.lock();
			boolean isOk=super.remove( o);
			if(isOk) {
				size.incrementAndGet();
			}
			return isOk;
		}finally {
			this.writeLock.unlock();
		}
		
		
	}

	@Override
	public void clear() {
		try {this.writeLock.lock();
			super.clear();
			size.set(0);
		}finally {
			this.writeLock.unlock();
		}
		
	}



	
	
	
}
